package com.hqd.jjvm.rtda.heap;

import com.hqd.jjvm.classformat.ClassMemberInfo;
import com.hqd.jjvm.classformat.attributeinfo.AttributeInfo;
import com.hqd.jjvm.classformat.attributeinfo.RuntimeVisibleAnnotations;
import com.hqd.jjvm.classformat.attributeinfo.Signature;
import com.hqd.jjvm.classformat.constantpool.ConstantPool;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class JClassMember extends BaseMember {
    private String descriptor;
    private JClass jClass;
    /**
     * 签名
     */
    private JSignature jSignature;
    private byte[] annoBytes;

    /**
     * 判断访问权限
     *
     * @param refJClass
     * @return
     */
    public boolean isAccessibleTo(JClass refJClass) {
        return this.jClass.isPublic() || this.jClass.getPackageName().equals(refJClass.getPackageName());
    }

    protected void newJClassMember(ClassMemberInfo classMemberInfo, JClass jClass, List<ConstantPool> constantPool) {
        for (AttributeInfo attr : classMemberInfo.getAttributeInfos()) {
            if (attr instanceof Signature) {//属性签名
                JSignature signature = new JSignature();
                signature.setName(constantPool.get(attr.getAttributeNameIndex()).getVal().toString());
                signature.setSignature(constantPool.get(((Signature) attr).getSignatureIndex()).getVal().toString());
                this.setJSignature(signature);
            } else if (attr instanceof RuntimeVisibleAnnotations) {
                this.annoBytes = attr.getByteCodes();
            }
            newDescInfo(attr, jClass, constantPool);
        }
        this.setAccessFlags(classMemberInfo.getAccessFlags());
        this.setDescriptor(constantPool.get(classMemberInfo.getDescriptorIndex()).getVal().toString());
        this.setName(constantPool.get(classMemberInfo.getNameIndex()).getVal().toString());
        this.setJClass(jClass);
    }

    /**
     * 具体细节由子类具体实现
     *
     * @param attr
     * @param jClass
     * @param constantPool
     */
    protected void newDescInfo(AttributeInfo attr, JClass jClass, List<ConstantPool> constantPool) {
    }
}
